﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Controller_App
{
    /// <summary>
    /// Form zum einstelle und ANWENDEN der Gewichtsänderungen bzw Fehlerflächen.
    /// _ctrl muss initialisiert werden
    /// </summary>
    public partial class frm_Gewicht_edit : Form
    {
        private List<Tuple<string, double>> _WEIGHTS;
        public IVisual.I_Controller _ctrl { get; set; }

        private int _chart_3d_rotx;
        private int _chart_3d_rotz;
        private int _chart_3d_rot_inc = 10;

        public frm_Gewicht_edit()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Initialisiert die Gewicht-LV aus der Liste
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_Gewicht_edit_Shown(object sender, EventArgs e)
        {
            this._lv_main.Items.Clear();

            for(int i=0; i<_WEIGHTS.Count; i++)
            {
                ListViewItem _lvi = new ListViewItem();
                _lvi.SubItems[0].Text = _WEIGHTS[i].Item1;
                _lvi.SubItems.Add(_WEIGHTS[i].Item2.ToString());

                this._lv_main.Items.Add(_lvi);
            }
        }

        /// <summary>
        /// Wendet ALLE Gewichtsänderungen an
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cmd_ok_Click(object sender, EventArgs e)
        {
            _lv_main_SelectedIndexChanged(null, null);

            _WEIGHTS.Clear();
            for (int i = 0; i < this._lv_main.Items.Count; i++)
            {
                _WEIGHTS.Add(new Tuple<string, double>(this._lv_main.Items[i].SubItems[0].Text, Convert.ToDouble(this._lv_main.Items[i].SubItems[1].Text)));
            }

            this._ctrl.SET_WEIGHTS(this._WEIGHTS);
        }

        /// <summary>
        /// Konfiguriert die Chart3D, holt die Gewichte ab
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frm_Gewicht_edit_Load(object sender, EventArgs e)
        {
            // Chart einstellungen setzten
            _chart_3d_rotz = this._Chart3D.ChartArea.View.RotationZ;
            _chart_3d_rotx = this._Chart3D.ChartArea.View.RotationX;
            this._Chart3D.ChartGroups[0].Contour.IsZoned = true;
            this._Chart3D.ChartGroups.ContourStyles.ColorSet = C1.Win.C1Chart3D.ColorSetEnum.Rainbow;
            this._Chart3D.ChartGroups[0].Contour.NumLevels = 100;
            this._Chart3D.ChartGroups[0].Elevation.IsMeshed = true;
            this._Chart3D.Visible = false; // um Default-View auszublenden

            // Chart-3D LV setzten
            this._lv_3d_main.Items.Clear();
            string[] _ret = this._ctrl.GET_3D_Dim();
            for (int i = 0; i < _ret.Length; i++)
                this._lv_3d_main.Items.Add(_ret[i]);

            if (this._lv_3d_main.Items.Count > 0)
                this._lv_3d_main.Items[0].Selected = true;

            // Gewichte abholen
            this._WEIGHTS = this._ctrl.GET_WEIGHTS();
        }

        /// <summary>
        /// führt die rotationen der Surface anhand der 4 Buttons durch
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _tlb_surface_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            switch (this._tlb_surface.Buttons.IndexOf(e.Button))
            {
                case 1:
                    _chart_3d_rotz += _chart_3d_rot_inc;
                    if (_chart_3d_rotz > 360)
                        _chart_3d_rotz -= 360;
                    this._Chart3D.ChartArea.View.RotationZ = _chart_3d_rotz;
                    break;
                case 0:
                    _chart_3d_rotz -= _chart_3d_rot_inc;
                    if (_chart_3d_rotz < 0)
                        _chart_3d_rotz += 360;
                    this._Chart3D.ChartArea.View.RotationZ = _chart_3d_rotz;
                    break;
                case 2:
                    _chart_3d_rotx += _chart_3d_rot_inc;
                    if (_chart_3d_rotx > 360)
                        _chart_3d_rotx -= 360;
                    this._Chart3D.ChartArea.View.RotationX = _chart_3d_rotx;
                    break;
                case 3:
                    _chart_3d_rotx -= _chart_3d_rot_inc;
                    if (_chart_3d_rotx < 0)
                        _chart_3d_rotx += 360;
                    this._Chart3D.ChartArea.View.RotationX = _chart_3d_rotx;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// startet das erneute Plotten einer surface, wenn ein anderes Neuron ausgewählt wurde
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _lv_3d_main_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this._lv_3d_main.SelectedItems.Count != 1)
                return;

            // Aus dem Label die Indexe extrahieren
            int l_i = Convert.ToInt32(this._lv_3d_main.SelectedItems[0].Text.Split(new string[] { " - " }, StringSplitOptions.None)[0]);
            int n_i = Convert.ToInt32(this._lv_3d_main.SelectedItems[0].Text.Split(new string[] { " - " }, StringSplitOptions.None)[1]);

            // Daten berechnen lassen
            Tuple<float[,], double, double, double> _data = this._ctrl.Calc_3D(l_i, n_i, 0, 1, this._nud_err_schw.Value * 2);

            this._Chart3D.Visible = true;
            this._Chart3D.ChartGroups[0].ChartData.SetGrid = new C1.Win.C1Chart3D.Chart3DDataSetGrid(_data.Item2, _data.Item3, _data.Item4, _data.Item4, _data.Item1);
        }

        /// <summary>
        /// Textfelder für die Gewichtsänderunge bei ändern der selektion aktualiseren
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _lv_main_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this._lv_main.SelectedItems.Count != 1)
                return;

            // Alten wert in die LV schreiben
            for (int i = 0; i < this._lv_main.Items.Count; i++)
                if (this._lv_main.Items[i].SubItems[0].Text == this._tb_beschr.Text)
                {
                    try
                    {
                        this._lv_main.Items[i].SubItems[1].Text = Convert.ToDouble(this._tb_val.Text).ToString();
                    }
                    catch (Exception) { }

                    break;
                }

            //  Neuen wert in die TBs setzten
            this._tb_beschr.Text = this._lv_main.SelectedItems[0].SubItems[0].Text;
            this._tb_val.Text = this._lv_main.SelectedItems[0].SubItems[1].Text;
        }

        private void _cmd_close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Neues Plotten der Fehlerfläche auslösen, wenn die abweichung geändert wurde
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _nud_err_schw_ValueChanged(object sender, EventArgs e)
        {
            this._lv_3d_main_SelectedIndexChanged(null, null);
        }
    }
}
